#include<stdio.h>
#include<stdlib.h>
#include <errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<time.h>
#include<sys/select.h>
#include<string.h>
#define ERR_EXIT(m)   do{ perror(m); exit(EXIT_FAILURE);}while(0)
int main(void)
{
    //创建监听套接字
    int fd_listen;
    if( (fd_listen =socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) == -1)
        ERR_EXIT("listen");
    
    struct sockaddr_in servaddr;
    memset(&servaddr,0,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(3000);
    servaddr.sin_addr.s_addr = inet_addr("192.168.99.123");
    //开启重复利用   这样关闭后可以立刻再启动服务器，不必等待WAIT状态
    int on = 1;
    if( setsockopt(fd_listen,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))== -1)
        ERR_EXIT("setsockopt");
    if( bind(fd_listen,(struct sockaddr *)&servaddr,sizeof(servaddr))== -1)
        ERR_EXIT("bind");
    if( listen(fd_listen,SOMAXCONN)== -1)
        ERR_EXIT("listen");

    fd_set  reads, temp;

    FD_ZERO(&reads);
    FD_ZERO(&temp);
    FD_SET(fd_listen,&reads);

    int maxfd=fd_listen;
    //客户端信息
    struct sockaddr_in cliaddr;
    socklen_t clilen = sizeof(cliaddr);
    while (1)
    {
        temp = reads;
       // printf("temp %ld\n",temp);
        int ret = select(maxfd+1,&temp,NULL,NULL,NULL);

        if( FD_ISSET(fd_listen,&temp))
        {
            printf("开始建立连接\n");
            int cfd = accept(fd_listen,(struct sockaddr *)&cliaddr,&clilen);
            if(cfd == -1)
                ERR_EXIT("accept");

            
            maxfd = (maxfd < cfd)?cfd:maxfd;
            printf("IP = %s, Port = %d \n",inet_ntoa(cliaddr.sin_addr),ntohs(cliaddr.sin_port));
            FD_SET(cfd,&reads);
        }
        for(int i =fd_listen+1;i<=maxfd;i++)
        {
            if( FD_ISSET(i,&temp))
            {
                char buf[1024]={0};
                int len = read(i,buf,sizeof(buf));
                if( len == -1)
                    ERR_EXIT("read");
                else if( len ==0 )
                {
                    printf("客户端关闭连接\n");
                    close(i);
                    FD_CLR(i,&reads);
                }
                else
                {
                    printf("收到的数据为：%s\n",buf);
                    write(i,buf,strlen(buf)+1);
                    memset(buf,0,sizeof(buf));
                }
                
            }

        }
    }
    

    close(fd_listen);
    return 0;
}